package net.oschina.git.fsppp.manager;

import net.oschina.git.fsppp.dao.DirDao;
import net.oschina.git.fsppp.model.P3Dir;
import net.oschina.git.fsppp.model.P3Disk;
import net.oschina.git.fsppp.model.P3FAT;
import net.oschina.git.fsppp.model.SimpleResponse;
import net.oschina.git.fsppp.utils.P3Utils;

import java.io.File;
import java.io.InputStream;
import java.util.*;

/**
 * 文件管理类
 * Created by guin_guo on 2016/10/8.
 */
public class FileManager implements IFileManager{

    protected DirDao dirDao;

    public FileManager() {
        this.dirDao = DirDao.getInstance();
    }

    public static class DefaultInstance {
        public static FileManager instance = new FileManager();
    }
    public static FileManager getInstance() {
        return DefaultInstance.instance;
    }

    public static Set disks = new HashSet<>();
    public static final String BASEPATH = System.getProperty("user.dir") + "\\src\\main\\resources\\";
    public static final String DISK_STORE_FILE = "zdisk";


    /**
     * 初始化磁盘，格式化磁盘
     * @return
     * @throws Exception
     */
    @Override
    public SimpleResponse initDisk() {
        InputStream is = null;
        SimpleResponse<Set> response = new SimpleResponse<>();
        try {
            is = FileManager.class.getClassLoader().getResourceAsStream(DISK_STORE_FILE);
            byte[] b = new byte[1];
            while (is.read(b) > 0) {
                char s = (char) (b[0]);
                if (s != 44) {
                    disks.add(s);
                }
            }
            is.close();
            Iterator iterator = disks.iterator();
            while (iterator.hasNext()) {
                char cd = (char) iterator.next();
                File file = new File(BASEPATH + "\\" + cd + ".disk");
                if (!file.exists()) {
                    file.createNewFile();
                    //建立磁盘
                    P3Disk disk = new P3Disk();
                    disk.setName(cd + "");
                    //文件分配表
                    P3FAT fat = new P3FAT();
                    fat.initFat();
                    fat.setDisk(disk.getName());
                    //初始化磁盘
                    disk.initDisk(fat);
                    P3Utils.write2DiskFile(disk);
                }
            }
            response.setStatus(Boolean.TRUE);
            response.setEntity(disks);
            response.setMsg("success");
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            e.printStackTrace();
            response.setStatus(Boolean.FALSE);
            response.setMsg(e.getMessage());
            return response;
        } finally {
            try {
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 格式化指定磁盘
     * @return
     * @throws Exception
     */
    public SimpleResponse initDisk(String diskName) {
        SimpleResponse<Set> response = new SimpleResponse<>();
        try {
            File file = new File(BASEPATH + "\\" + diskName + ".disk");
            if (file.exists()) {
                //建立磁盘
                P3Disk disk = new P3Disk();
                disk.setName(diskName + "");
                //文件分配表
                P3FAT fat = new P3FAT();
                fat.initFat();
                fat.setDisk(disk.getName());
                //初始化磁盘
                disk.initDisk(fat);
                P3Utils.write2DiskFile(disk);
            }
            response.setStatus(Boolean.TRUE);
            response.setEntity(disks);
            response.setMsg("success");
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            e.printStackTrace();
            response.setStatus(Boolean.FALSE);
            response.setMsg(e.getMessage());
            return response;
        }
    }

    /**
     * 磁盘对象转化为P3Dir
     * @return
     * @throws Exception
     */
    @Override
    public SimpleResponse<List<P3Dir>> listDisk() {
        SimpleResponse<List<P3Dir>> response = new SimpleResponse<>();
        try {
            if (disks.size() == 0) {
                InputStream is = FileManager.class.getClassLoader().getResourceAsStream(DISK_STORE_FILE);
                byte[] b = new byte[1];
                while (is.read(b) > 0) {
                    char s = (char)(b[0]);
                    if (s != 44) {
                        disks.add(s);
                    }
                }
                is.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.setStatus(Boolean.FALSE);
            response.setMsg(e.getMessage());
            return response;
        }
        List<P3Dir> diskDirs = new ArrayList<>(disks.size());
        for (Object d : disks) {
            P3Dir dir = new P3Dir();
            dir.setName(d.toString() + ":");
            dir.setPath(d.toString() + ":\\");
            dir.setType(P3Dir.TYPE_OF_DIR);
            dir.setStartNum(0);
            dir.setPid(0);
            dir.setLength(1);
            diskDirs.add(dir);
        }
        response.setStatus(Boolean.TRUE);
        response.setEntity(diskDirs);
        response.setMsg("success");
        return response;
    }

    /**
     * 删除磁盘，将导致无法撤销后果，比如说 文件全部没了
     * @return
     * @throws Exception
     */
    @Override
    public SimpleResponse cleanDisks() {
        InputStream is = null;
        SimpleResponse response = new SimpleResponse<>();
        try {
            is = FileManager.class.getClassLoader().getResourceAsStream(DISK_STORE_FILE);
            byte[] b = new byte[1];
            while (is.read(b) > 0) {
                char s = (char) (b[0]);
                if (s != 44) {
                    disks.add(s);
                }
            }
            is.close();
            Iterator iterator = disks.iterator();
            while (iterator.hasNext()) {
                char cd = (char) iterator.next();
                File file = new File(BASEPATH + "\\" + cd + ".disk");
                if (file.exists()) {
                    file.delete();
                }
            }
            response.setStatus(Boolean.TRUE);
            response.setEntity(disks);
            response.setMsg("success");
            return response;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 根据路径创建文件
     * @param path  c:\Test
     * @param name  hello.java
     * @return  P3Dir
     *              - type: 0
     *              - path: c:\Test
     *              - name: hello.java
     *              - attr: java
     *              - content: Byte[]
     *              ...
     */
    @Override
    public SimpleResponse<P3Dir> createFile(String path, String name) {
        SimpleResponse<P3Dir> simpleResponse = new SimpleResponse<>();
        try {
            P3Dir dir = dirDao.createFile(path, name);
            simpleResponse.setEntity(dir);
            simpleResponse.setStatus(Boolean.TRUE);
            simpleResponse.setMsg("创建文件[" + name + "]成功");
        } catch (Exception e) {
            e.printStackTrace();
            simpleResponse.setStatus(Boolean.FALSE);
            simpleResponse.setMsg(e.getMessage());
        }
        return simpleResponse;
    }

    @Override
    public SimpleResponse<P3Dir> editFile(P3Dir dir) {
        SimpleResponse<P3Dir> simpleResponse = new SimpleResponse<>();
        try {
            P3Dir persist = dirDao.getByPath(dir.getPath());
            if (persist == null) {
                simpleResponse.setStatus(Boolean.FALSE);
                simpleResponse.setMsg(dir.getPath() + " 文件不存在");
                return simpleResponse;
            }
            dirDao.editFile(persist, dir);
        } catch (Exception e) {
            e.printStackTrace();
            simpleResponse.setStatus(Boolean.FALSE);
            simpleResponse.setMsg(e.getMessage());
            return simpleResponse;
        }
        simpleResponse.setStatus(Boolean.TRUE);
        simpleResponse.setMsg("success");
        simpleResponse.setEntity(dir);
        return simpleResponse;
    }

    @Override
    public SimpleResponse<P3Dir> deleteFile(P3Dir dir) {
        SimpleResponse<P3Dir> simpleResponse = new SimpleResponse<>();
        try {
            P3Dir persist = dirDao.getById(dir.getPath().substring(0, 1), dir.getStartNum());
            if (persist == null) {
                simpleResponse.setStatus(Boolean.FALSE);
                simpleResponse.setMsg(dir.getPath() + " 文件不存在");
                return simpleResponse;
            }
            if (persist.getType() == P3Dir.TYPE_OF_DIR) {
                dirDao.deleteDir(persist);
            } else {
                dirDao.deleteFile(persist);
            }
        } catch (Exception e) {
            e.printStackTrace();
            simpleResponse.setStatus(Boolean.FALSE);
            simpleResponse.setMsg(e.getMessage());
            return simpleResponse;
        }
        simpleResponse.setStatus(Boolean.TRUE);
        simpleResponse.setMsg("success");
        simpleResponse.setEntity(dir);
        return simpleResponse;
    }

    @Override
    public SimpleResponse<String> showFileContent(P3Dir dir) {
        SimpleResponse<String> simpleResponse = new SimpleResponse<>();
        try {
            if (dir.isOpen()) {
                simpleResponse.setMsg("success");
                simpleResponse.setStatus(Boolean.TRUE);
                if (dir.getContent() != null) {
                    simpleResponse.setEntity(new String(P3Utils.Byte2byte(dir.getContent())));
                }
                return simpleResponse;
            } else {
                simpleResponse.setStatus(Boolean.FALSE);
                simpleResponse.setMsg("请先打开文件");
            }
        } catch (Exception e) {
            e.printStackTrace();
            simpleResponse.setStatus(Boolean.FALSE);
            simpleResponse.setMsg(e.getMessage());
            return simpleResponse;
        }
        return simpleResponse;
    }

    @Override
    public SimpleResponse openFile(P3Dir dir) {
        SimpleResponse<P3Dir> simpleResponse = new SimpleResponse<>();
        try {
            if (!dir.isOpen()) {
                dir.setIsOpen(true);
                simpleResponse.setMsg("success");
                simpleResponse.setStatus(Boolean.TRUE);
                simpleResponse.setEntity(dir);
                return simpleResponse;
            } else {
                simpleResponse.setStatus(Boolean.FALSE);
                simpleResponse.setMsg("文件已经打开");
                simpleResponse.setEntity(dir);
            }
        } catch (Exception e) {
            e.printStackTrace();
            simpleResponse.setStatus(Boolean.FALSE);
            simpleResponse.setMsg(e.getMessage());
            return simpleResponse;
        }
        return simpleResponse;
    }

    @Override
    public SimpleResponse readFile(P3Dir dir) {
        SimpleResponse<P3Dir> simpleResponse = new SimpleResponse<>();
        try {
            if (dir.isOpen()) {
                simpleResponse.setMsg("success");
                simpleResponse.setStatus(Boolean.TRUE);
                simpleResponse.setEntity(dir);
                return simpleResponse;
            } else {
                simpleResponse.setStatus(Boolean.FALSE);
                simpleResponse.setMsg("请先打开文件");
                simpleResponse.setEntity(dir);
            }
        } catch (Exception e) {
            e.printStackTrace();
            simpleResponse.setStatus(Boolean.FALSE);
            simpleResponse.setMsg(e.getMessage());
            return simpleResponse;
        }
        return simpleResponse;
    }

    @Override
    public SimpleResponse writeFile(P3Dir dir, StringBuffer content) {
        SimpleResponse<P3Dir> simpleResponse = new SimpleResponse<>();
        try {
            if (dir.isOpen()) {
                dir.setContent(P3Utils.byte2Byte(content.toString().getBytes()));
                simpleResponse = editFile(dir);
                return simpleResponse;
            } else {
                simpleResponse.setStatus(Boolean.FALSE);
                simpleResponse.setMsg("请先打开文件");
                simpleResponse.setEntity(dir);
            }
        } catch (Exception e) {
            e.printStackTrace();
            simpleResponse.setStatus(Boolean.FALSE);
            simpleResponse.setMsg(e.getMessage());
            return simpleResponse;
        }
        return simpleResponse;
    }

    @Override
    public SimpleResponse closeFile(P3Dir dir) {
        SimpleResponse<P3Dir> simpleResponse = new SimpleResponse<>();
        try {
            if (dir.isOpen()) {
                dir.setIsOpen(false);
                simpleResponse.setMsg("success");
                simpleResponse.setStatus(Boolean.TRUE);
                simpleResponse.setEntity(dir);
                return simpleResponse;
            } else {
                simpleResponse.setStatus(Boolean.FALSE);
                simpleResponse.setMsg("文件尚未打开");
                simpleResponse.setEntity(dir);
            }
        } catch (Exception e) {
            e.printStackTrace();
            simpleResponse.setStatus(Boolean.FALSE);
            simpleResponse.setMsg(e.getMessage());
            return simpleResponse;
        }
        return simpleResponse;
    }

    @Override
    public SimpleResponse changeAttr(P3Dir dir, String attr) {
        SimpleResponse<P3Dir> simpleResponse = new SimpleResponse<>();
        try {
            if (dir.isOpen()) {
                dir.setAttr(attr);
                simpleResponse = editFile(dir);
                return simpleResponse;
            } else {
                simpleResponse.setStatus(Boolean.FALSE);
                simpleResponse.setMsg("请先打开文件");
                simpleResponse.setEntity(dir);
            }
        } catch (Exception e) {
            e.printStackTrace();
            simpleResponse.setStatus(Boolean.FALSE);
            simpleResponse.setMsg(e.getMessage());
            return simpleResponse;
        }
        return simpleResponse;
    }
}
